package quick.api.app.service;

import com.alibaba.fastjson.JSONObject;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import net.coobird.thumbnailator.geometry.Region;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webdm.business.bean.Context;
import webdm.business.bean.ResponseDTO;
import webdm.business.component.AbstractPipelineComponent;
import webdm.business.util.ValueUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * 使用方法
 * 1. 指定大小缩放 ?w=500&h=500
 * 2. 按比例缩放 ?scale=0.2
 * 3. 旋转 ?h=500&w=500&rotate=90
 * 4. 裁剪 ?h=500&w=500&source_w=900&position=center
 */
public class ImageService extends AbstractPipelineComponent {

    private Logger logger = LoggerFactory.getLogger(ImageService.class);
    private String rootPath;
    private ResponseDTO notFound = ResponseDTO.getInstance(404, "not found");
    private ResponseDTO pathIsEmpty = ResponseDTO.getInstance(404, "path参数不能为空");
    private ResponseDTO overMaximum = ResponseDTO.getInstance(404, "超过处理的最大值");
    private long maximum;

    @Override
    public void setConfig(JSONObject config) {
        super.setConfig(config);
        this.rootPath = ValueUtil.getValue(config, "root_path", "./");
        this.maximum = ValueUtil.getValue(config, "max_length_mb", 2) * 1024 * 1024;
    }

    @Override
    public ResponseDTO process(Context context) {
        String imagePath = context.get("param.path", null);
        if(StringUtils.isBlank(imagePath)){
            return pathIsEmpty;
        }else{
            File file = new File(rootPath + "/" + imagePath);
            if(!file.exists()){
                return notFound;
            }else if(file.length() > maximum){
                return overMaximum;
            }else{

                int rotate = context.get("param.rotate", 0);
                int w = context.get("param.w", 0);
                int h = context.get("param.h", w);
                int sourceW = context.get("param.source_w", 0);
                int sourceH = context.get("param.source_h", 0);
                float scale = context.get("param.scale", 0f);
                float quality = context.get("param.quality", 0f);
                boolean keepAspectRatio = context.get("param.keep_aspect_ratio", false);
//                boolean crop = context.get("param.crop", false);
                String position = context.get("param.position", "center");
                String outputFormat = context.get("param.format", null);
                String output = context.get("param.output", null);

                Thumbnails.Builder builder =  Thumbnails.of(file.getAbsolutePath());

                if(sourceW > 0){

                    Positions p = Positions.CENTER;
                    if("top".equals(position)){
                        p = Positions.TOP_CENTER;
                    }else if("top_left".equals(position)){
                        p = Positions.TOP_LEFT;
                    }else if("top_right".equals(position)){
                        p = Positions.TOP_RIGHT;
                    }else if("bottom".equals(position)){
                        p = Positions.BOTTOM_CENTER;
                    }else if("bottom_left".equals(position)){
                        p = Positions.BOTTOM_LEFT;
                    }else if("bottom_right".equals(position)){
                        p = Positions.BOTTOM_RIGHT;
                    }

                    sourceH = sourceH == 0 ? sourceW : sourceH;

                    builder.sourceRegion(p, sourceW, sourceH);
//                    builder.scale(scale > 0 ? scale : 1.0f);
//                    builder.size(w, h);
                    w = w == 0 ? 100 : w;
                    h = h == 0 ? w : h;
                    builder.size(w, h);
                }else if(w > 0 || h > 0){
                    w = w == 0 ? 100 : w;
                    h = h == 0 ? w : h;
                    builder.size(w, h);
                }

                if(scale > 0){
                    builder.scale(scale);
                }
                if(rotate > 0){
                    builder.rotate(rotate);
                }
                if(quality > 0){
                    builder.outputQuality(quality);
                }
                if(keepAspectRatio){
                    builder.keepAspectRatio(true);
                }
                if(StringUtils.isNotBlank(outputFormat)){
                    builder.outputFormat(outputFormat);
                }

                if(StringUtils.isNotBlank(output)){

                    if("overwrite".equals(output)){
                        String originFile = file.getAbsolutePath();
                        File outputFile = new File(file.getParentFile().getAbsolutePath() + "/tmp_" + file.getName());
                        try {
                            builder.toFile(outputFile);
                            if(outputFile.exists() && outputFile.length() > 100){
                                file.delete();
                                outputFile.renameTo(new File(originFile));
                            }
                        } catch (IOException e) {
                            logger.error("overwrite模式保存图片异常" + outputFile.getAbsolutePath(), e);
                        }
                    }else{
                        File outputFile = new File(output);
                        if(!outputFile.getParentFile().exists()){
                            outputFile.getParentFile().mkdirs();
                        }
                        try {
                            builder.toFile(outputFile);
                        } catch (IOException e) {
                            logger.error("保存图片异常" + outputFile.getAbsolutePath(), e);
                        }
                    }

                }else{
                    HttpServletResponse response = context.getResponse();
                    String name = file.getName();
                    if(StringUtils.isNotBlank(outputFormat)){
                        response.setContentType("image/" + outputFormat);
                    }else if(name.contains(".")){
                        String arr[] =  name.split("\\.");
                        response.setContentType("image/" + arr[arr.length - 1]);
                    }

                    response.setCharacterEncoding("UTF-8");
                    response.setHeader("Content-Disposition", "inline; filename=" + name);
                    OutputStream outputStream = null;
                    try {
                        outputStream = response.getOutputStream();
                        builder.toOutputStream(outputStream);
                        outputStream.close();

                    } catch (IOException e) {
                        logger.error("写入图片outputStream异常, path " + file.getAbsolutePath() , e.toString());
                        if(outputStream != null){
                            try {
                                IOUtils.copy(new FileInputStream(file), outputStream);
                                outputStream.close();
                            } catch (Exception ex) {
                                logger.error("原始图片写入outputStream异常, path " + file.getAbsolutePath() , e.toString());
                                return ResponseDTO.getInstance(500, "图片处理异常");
                            }
                        } else {
                            return ResponseDTO.getInstance(500, "图片处理异常");
                        }
                    }
                }
                return ResponseDTO.getSuccessInstance();

            }

        }
    }
}
